package com.csii.activiti.server.core.listener;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.csii.activiti.server.abstraction.constant.MessageType;
import com.csii.activiti.server.abstraction.entity.ActFlowRemoteCallback;
import com.csii.activiti.server.abstraction.entity.ActReceivedBy;
import com.csii.activiti.server.abstraction.entity.ActSendMessage;
import com.csii.activiti.server.abstraction.service.ActMessageService;
import com.csii.activiti.server.core.constant.CommonConstant;
import com.csii.activiti.server.core.entity.ActFlowNode;
import com.csii.activiti.server.core.entity.db.ActFlowPublishConfigEntity;
import com.csii.activiti.server.core.mapper.ActFlowNodeMapper;
import com.csii.activiti.server.core.mapper.ActFlowPublishConfigurationMapper;
import com.csii.activiti.server.core.service.FlowCallbackManagementService;
import com.csii.activiti.server.core.utils.ELUtils;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.activiti.engine.impl.persistence.entity.VariableInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class FlowUrgingDelegate implements JavaDelegate, Serializable {

    @Autowired
    private TaskService taskService;

    @Autowired
    private ActMessageService actMessageService;

    @Autowired
    private ActFlowNodeMapper actFlowNodeMapper;

    @Autowired
    private ActFlowPublishConfigurationMapper actFlowPublishConfigurationMapper;

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private FlowCallbackManagementService flowCallbackManagementService;


    @Override
    public void execute(DelegateExecution execution) {
        if (execution instanceof ExecutionEntityImpl) {
            ExecutionEntityImpl executionEntity = (ExecutionEntityImpl) execution;
            String processInstanceId = executionEntity.getProcessInstanceId();
            ExecutionEntityImpl parentExecutionEntity = executionEntity.getParent();
            List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
            Task task = taskList.get(0);
            ActFlowNode actFlowNode = actFlowNodeMapper.selectById(task.getTaskDefinitionKey()).transitionActFlowNode();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(executionEntity.getProcessDefinitionId()).singleResult();
            ActFlowPublishConfigEntity actFlowPublishConfigEntity = actFlowPublishConfigurationMapper.selectOne(new LambdaQueryWrapper<ActFlowPublishConfigEntity>().select(ActFlowPublishConfigEntity::getIconType, ActFlowPublishConfigEntity::getFlowName,ActFlowPublishConfigEntity::getSummary,ActFlowPublishConfigEntity::getManyConditionJson).eq(ActFlowPublishConfigEntity::getId, processDefinition.getDeploymentId()));
            String processName = actFlowPublishConfigEntity.getFlowName();

            //发送消息
            ActSendMessage sendMessage = new ActSendMessage();
            sendMessage.setTenantId(parentExecutionEntity.getTenantId());
            sendMessage.setProcessName(processName);
            sendMessage.setProcessDefinitionId(parentExecutionEntity.getProcessDefinitionId());
            sendMessage.setProcessKey(processDefinition.getKey());
            sendMessage.setProcessInstanceId(parentExecutionEntity.getProcessInstanceId());
            sendMessage.setInitiator(parentExecutionEntity.getStartUserId());
            Map<String, Object> formData = (Map<String, Object>) parentExecutionEntity.getVariableInstance(CommonConstant.FORM_DATA).getValue();
            sendMessage.setFormData(formData);
            List<ActReceivedBy> receivedByList = taskList.stream().map(item -> new ActReceivedBy(item.getId(), item.getAssignee())).collect(Collectors.toList());
            sendMessage.setReceivedByList(receivedByList);
            sendMessage.setCurrentNodeId(task.getTaskDefinitionKey());
            sendMessage.setCurrentNodeName(task.getName());
            VariableInstance callbackVariableInstance = parentExecutionEntity.getVariableInstance(CommonConstant.REMOTE_URL);
            if (callbackVariableInstance != null) {
                sendMessage.setCallbackList((List<ActFlowRemoteCallback>) callbackVariableInstance.getValue());
            }
            sendMessage.setCurrentDate(new Date());
            if (actFlowPublishConfigEntity != null){
                sendMessage.setIconType(actFlowPublishConfigEntity.getIconType());
                sendMessage.setSummary(ELUtils.getSummary(actFlowPublishConfigEntity.getSummary(),actFlowPublishConfigEntity.getManyConditionJson(),formData));
            }
            MessageType messageType = MessageType.valueOf(actFlowNode.getConfigurationItem().getFlowUrgingConfiguration().getRemindType());
            Map<String,Object> paramVariables = new HashMap<>();
            paramVariables.put("taskCreateTime",task.getCreateTime());
            //自动催办type=1
            paramVariables.put("type","1");
            sendMessage.setParamVariables(paramVariables);
            actMessageService.sendMessage(sendMessage, messageType);
            //触发回调
            flowCallbackManagementService.callback(sendMessage, messageType.getType());
        }
    }
}
